'use strict';
const { Service } = require('egg');
const dayjs = require("dayjs");
const { Op } = require('sequelize');
class RouterService extends Service {
    async companyList(where = {}) {
        return this.ctx.model.CompanyModel.findAll({
            where: {
                ...where,
                is_deleted: 0,
            },
            order: [
                // id 降序
                ['check_time', 'DESC']
            ],
        });
    }

    async bannerList(where) {
        return this.ctx.model.Banner.findAll({
            where: {
                ...where,
                is_deleted: 0,
            },
            order: [
                // id 降序
            ],
        });
    }

    async bannerDetail(id) {
        return this.ctx.model.Banner.findOne({
            where: {
                id,
                is_deleted: 0,
            },
        });
    }

    async storeRecordList(where, type) {
        if (type === '0') {
            return this.ctx.model.Matout.findAll({
                where: {
                    ...where,
                },
                include: [
                    {
                        model: this.ctx.model.MatModel,
                    }
                ]
            })
        } else if (type === '1') {
            return this.ctx.model.Matin.findAll({
                where: {
                    ...where,
                },
                include: [
                    {
                        model: this.ctx.model.MatModel,
                    }
                ]
            })
        } else {
            return []
        }
    }

    async matList(where) {
        console.log('where',where)
        const list = await this.ctx.model.MatModel.findAll({
            where: {
                mattype: '饲料',
                is_deleted: 0,
            },
            order: [
                // id 降序
            ],
            include: [
                {
                    model: this.ctx.model.Matout,
                    where: {
                        ...where
                    }
                }
            ]
        });
        return list
    }
    async matinAvgPrice(query) {
        const { company_id, mat } = query;
        // 前六个月
        let where = {
            buytime: {
                [Op.between]: [`${dayjs().subtract(6, 'month').format('YYYY-MM-DD')} 00:00:00`, `${dayjs().format('YYYY-MM-DD')} 23:59:59`]
            }
        }
        return this.ctx.model.Matin.findAll({
            where: {
                company: company_id,
                mat,
                is_deleted: 0,
                ...where
            },
            order: [
                // id 降序
            ],
        })
    }
    async roomList(query) {
        const { company_id } = query;
        return this.ctx.model.Room.findAll({
            where: {
                company: company_id,
                is_deleted: 0,
            },
            order: [
                // id 降序
            ],
        })
    }
    async deviceList(query) {
        const { room_id, company_id } = query;
        let where = {}
        if (room_id) {
            where.farmview = room_id
        }
        if (company_id) {
            where.company = company_id
        }
        return this.ctx.model.Device.findAll({
            where: {
                ...where,
                is_deleted: 0,
            },
            order: [
                // id 降序
            ],
        })
    }
    async deviceFaultsList(query) {
        const { room_id, date, status } = query;
        let fault_time = {
            [Op.between]: [`${date} 00:00:00`, `${date} 23:59:59`]
        }
        let where = {
            fault_time,
            is_deleted: 0,
        }
        if (room_id) {
            where.farmview = room_id
        }
        if (status) {
            where.status = status
        }
        return this.ctx.model.DeviceFaults.findAll({
            where: {
                ...where
            },
            order: [
                // id 降序
            ],
        })
    }
    async cameraList(query) {
        const { room_id } = query;
        let where = {}
        if (room_id) {
            where.farmview = room_id
        }

        return this.ctx.model.Device.findAll({
            where: {
                ...where,
                devtype: '摄像头',
                is_deleted: 0,
            },
            order: [
                // id 降序
            ],
        })
    }

    /**
     * 牛相关
     */
    async beefGroupList(where) {
        // 牛列表，但是牛的属性有一个品种，需要查询牛列表，并且根据品种分组
        return this.ctx.model.BeefModel.findAll({
            where: {
                ...where,
                is_deleted: 0,
                status: '在场'
            },
        })
    }
    async beefInOutList(where) {
        return this.ctx.model.Comptran.findAll({
            where: {
                ...where,
                is_deleted: 0,
            },
            include: [
                {
                    model: this.ctx.model.BeefModel,
                },
                {
                    model: this.ctx.model.CompanyModel,
                    as: 'nowCompany'
                },
                {
                    model: this.ctx.model.CompanyModel,
                    as: 'toCompany'
                }
            ]
        })
    }

    /**
     * 告警清单
     */
    async alarmList(query) {
        const { company_id } = query;
        const list = await this.ctx.model.AlarmLog.findAll({
            where: {
                company: company_id,
                is_deleted: 0,
            },
            order: [
                // id 降序
                ['id', 'DESC']
            ],
        })
        // 返回已处理的历史告警
        let alarmListHistory = []
        let waitAlarmList = []
        // 待处理的告警
        list.forEach(item => {
            if (item.status === 1) {
                alarmListHistory.push(item)
            }
            if (item.status === -1 || item.status === 0) {
                waitAlarmList.push(item)
            }
        })
        // 待处理中的告警需要分别统计三个类型
        // 生产进度
        let productAlarm = waitAlarmList.filter(item => item.category === '生产进度')
        let productionDelay = '0%'
        // 时间最近一条
        if (productAlarm.length) {
            productAlarm = productAlarm.sort((a, b) => {
                return new Date(b.created_time) - new Date(a.created_time)
            })
            productionDelay = productAlarm[0].threshold + '%'
        }

        // 饲料库存不足
        let matAlarm = waitAlarmList.filter(item => item.category === '库存不足')
        let inventoryShortage = '0吨'
        if (matAlarm.length) {
            matAlarm = matAlarm.sort((a, b) => {
                return new Date(b.created_time) - new Date(a.created_time)
            })
            inventoryShortage = matAlarm[0].threshold + '吨'
        }
        // 设备故障
        let deviceAlarm = waitAlarmList.filter(item => item.category === '设备故障')
        return {
            alarmListHistory,
            waitAlarmList,
            // 生产滞后
            productionDelay,
            // 库存不足
            inventoryShortage,
            // 设备故障
            equipmentFailure: deviceAlarm.length + '台'
        }
    }
    async handleAlarm(data) {
        const { id } = data;
        return this.ctx.model.AlarmLog.update({
            status: 1
        }, {
            where: {
                id,
            }
        })
    }
    async deleteAlarm(data) {
        const { id } = data;
        return this.ctx.model.AlarmLog.update({
            is_deleted: 1
        }, {
            where: {
                id,
            }
        })
    }

    /**
     * 考勤相关
     */
    async workLogToday(company_id) {
        let total = 0, online = 0, normal = 0, late = 0, leave = 0, early = 0, notClock = 0;
        // 当天
        const today = dayjs().format('YYYY-MM-DD')
        const userList = await this.ctx.model.Staff.findAll({
            where: {
                is_deleted: 0,
                company: company_id
            }
        })
        const list = await this.ctx.model.StaffWorkLog.findAll({
            where: {
                company: company_id,
                created_time: {
                    [Op.between]: [`${today} 00:00:00`, `${today} 23:59:59`]
                },
                is_deleted: 0,
            }
        })
        total = userList.length
        online = list.filter(item => item.work_type === 1).length // 上班
        normal = list.filter(item => item.work_type === 1 && item.delay === 0).length // 正常
        late = list.filter(item => item.work_type === 1 && item.delay === 1).length // 迟到
        early = list.filter(item => item.work_type === 2 && item.delay === 1).length // 早退
        leave = list.filter(item => item.work_type === 3).length // 请假
        return {
            total,
            online,
            // 正常
            normal,
            // 迟到
            late,
            // 请假
            leave,
            // 早退
            early,
            // 未打卡
            notClock,
        }
    }

    /**
     * 年龄分布
     */
    async ageDistribution(company_id) {
        let list = await this.ctx.model.Staff.findAll({
            where: {
                company: company_id,
                is_deleted: 0,
            }
        })
        let ageList = []
        list.forEach(item => {
            console.log('item.birthday',item.birthday)
            let age = dayjs().diff(item.birthday, 'year')
            ageList.push(age)
        })
        // 根据年龄计算年龄分布区间
        let ageDistribution = {
            '20岁以下': 0,
            '20-30岁': 0,
            '30-40岁': 0,
            '40-50岁': 0,
            '50-60岁': 0,
            '60岁以上': 0,
        }
        ageList.forEach(item => {
            if (item < 20) {
                ageDistribution['20岁以下']++
            } else if (item >= 20 && item < 30) {
                ageDistribution['20-30岁']++
            } else if (item >= 30 && item < 40) {
                ageDistribution['30-40岁']++
            } else if (item >= 40 && item < 50) {
                ageDistribution['40-50岁']++
            } else if (item >= 50 && item < 60) {
                ageDistribution['50-60岁']++
            } else if (item >= 60) {
                ageDistribution['60岁以上']++
            }
        })
        // 转成list
        let ageDistributionList = []
        for (let key in ageDistribution) {
            ageDistributionList.push({
                name: key,
                value: ageDistribution[key]
            })
        }
        return ageDistributionList
    }

    /**
     * 生产计划
     */
    async planList(company_id) {
        let list = [
            {
                name: '繁育',
                count: 0,
                planCount: 0,
                percent: '0%'
            },
            {
                name: '育肥',
                count: 0,
                planCount: 0,
                percent: '0%'
            },
            {
                name: '出栏',
                count: 0,
                planCount: 0,
                percent: '0%'
            }
        ]
        // 查找该牛场得生产计划
        const planList = await this.ctx.model.Plan.findAll({
            where: {
                company: company_id,
                status: 1,
                // 今天在开始与结束时间范围内的
                start_time: {
                    [Op.lte]: dayjs().format('YYYY-MM-DD HH:mm:ss')
                },
                end_time: {
                    [Op.gte]: dayjs().format('YYYY-MM-DD HH:mm:ss')
                }
            }
        })
        // 匹配计划
        planList.forEach(item => {
            if (item.type === '繁育') {
                list[0].planCount += item.count
            } else if (item.type === '育肥') {
                list[1].planCount += item.count
            } else if (item.type === '出栏') {
                list[2].planCount += item.count
            }
        })
        // 查找实际数量
        // TODO
        return list
    }
    /**
     * 登录
     */
    async login(data) {
        const { phone, password } = data;
        const find = await this.ctx.model.User.findOne({
            where: {
                telephone: phone,
                password,
                is_deleted: 0,
            }
        })
        if (find) {
            return find
        } else {
            throw new Error('账号或密码错误')
        }
    }

    /**
     * 繁育指标数据
     * 1. 发情数 取 hybrid表
     * 2. 流产数 取 calving 表
     * 3. 产犊数 取 calving 表
     * 4. 配种数 取 hybrid表 表
     * 5. 娩娠数 取 calving 表
     */
    async breedIndex({ company_id, breed }) {
        let where = {
            company: company_id,
            is_deleted: 0,
        }
        if (breed && breed !== 'undefined') {
            where.breed = breed
        }
        // 查找牛场下的牛只
        const beefList = await this.ctx.model.BeefModel.findAll({
            where
        })
        // 牛只编号
        let beefIdList = beefList.map(item => item.id)
        /**
         * 配种表记录
         */
        const estrusList = await this.ctx.model.Hybrid.findAll({
            where: {
                is_deleted: 0,
            }
        })
        let filterEstrusList = estrusList.filter(item => beefIdList.includes(item.beef))
        // 发情数
        let estrusCount = filterEstrusList.filter(item => item.estdate).length
        // 配种数 种牛存在
        let hybridCount = filterEstrusList.filter(item => item.mater).length
        // 娩娠数
        let calvingCount = filterEstrusList.filter(item => item.firstpreg).length

        /**
         * 流产、产犊表记录
         */
        let hybridIdList = filterEstrusList.map(item => item.id)
        const calvingList = await this.ctx.model.Calving.findAll({
            where: {
                hybrid: hybridIdList,
                is_deleted: 0,
            }
        })
        // 流产数
        let miscarryCount = calvingList.filter(item => item.miscarry === 1).length
        // 产犊数
        let calveCount = calvingList.filter(item => item.miscarry === 0).length

        return [
            {
                name: '发情数',
                value: estrusCount
            },
            {
                name: '流产数',
                value: miscarryCount
            },
            {
                name: '产犊数',
                value: calveCount
            },
            {
                name: '配种数',
                value: hybridCount
            },
            {
                name: '娩娠数',
                value: calvingCount
            }
        ]
    }

    /**
     * 疾病指标数据
     */
    async diseaseList({ company_id, breed }) {
        let where = {
            company: company_id,
            is_deleted: 0,
        }
        if (breed && breed !== 'undefined') {
            where.breed = breed
        }
        // 查找牛场下的牛只
        const beefList = await this.ctx.model.BeefModel.findAll({
            where
        })
        // 牛只编号
        let beefIdList = beefList.map(item => item.id)
        // 病例表
        const diseaseList = await this.ctx.model.Disease.findAll({
            where: {
                beef: beefIdList,
                is_deleted: 0,
            }
        })
        // 康复头数
        let recoverCount = diseaseList.filter(item => item.status === '康复').length
        // 统计患病类型
        let diseaseTypeList = []
        diseaseList.forEach(item => {
            // 统计每个疾病类型的数量
            let findIndex = diseaseTypeList.findIndex(type => type.name === item.distype)
            if (findIndex === -1) {
                diseaseTypeList.push({
                    name: item.distype,
                    value: 1
                })
            } else{
                diseaseTypeList[findIndex].value++
            }
        })

        return {
            recoverCount,
            diseaseTypeList
        }
    }


    /**
     * 警定时任务
     */
    async reviewAlarm() {
        // 查找所有牛场
        let companyList = await this.ctx.model.CompanyModel.findAll({
            where: {
                is_deleted: 0,
            }
        })
        // 遍历每个牛场
        for (let i = 0; i < companyList.length; i++) {
            this.createAlarm(companyList[i].id)
        }
    }

    /**
     * 根据公司创建告警
     */
    async createAlarm(company_id) {

        // 告警规则配置
        let alarmRuleList = await this.ctx.model.AlarmRule.findAll({
            where: {
                is_deleted: 0,
                status: 1,
                company: company_id
            }
        })
        /**
         * 库存
         */
        // 库存预警
        let matAlarmRule = alarmRuleList.find(item => item.category === '库存不足')
        // 查找库存计算库存总量
        let matList = await this.ctx.model.MatModel.findAll({
            where: {
                company: company_id,
                mattype: '饲料',
            }
        })
        let total = matList.reduce((prev, next) => {
            return prev + next.count
        },0)
        // 判断库存是否不足
        if (total < matAlarmRule.threshold) {
            // 创建告警
            await this.ctx.model.AlarmLog.create({
                company: company_id,
                category: '库存不足',
                threshold: total,
                unit: '吨',
                is_deleted: 0,
                description: '库存不足',
                status: 0
            })
        }

        /**
         * 生产进度 TODO
         */
        // 生产进度
        let productAlarmRule = alarmRuleList.find(item => item.category === '生产进度')
    }
}

module.exports = RouterService;
